package com.anran.netty.server;


import com.anran.netty.protocol.MessageCodecSharable;
import com.anran.netty.protocol.ProcotolFrameDecoder;
import com.anran.netty.server.handler.*;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;

/**
 * 聊天--服务端
 */
@Slf4j
public class ChatServer {



    public static void main(String[] args) throws InterruptedException {

        NioEventLoopGroup boss = new NioEventLoopGroup();
        NioEventLoopGroup worker = new NioEventLoopGroup();
        //协议
        MessageCodecSharable MESSAGE = new MessageCodecSharable();
        //日志
        LoggingHandler LOG = new LoggingHandler(LogLevel.DEBUG);
        //登陆处理器
        LoginRequestMessageHandler loginHandler = new LoginRequestMessageHandler();
        //聊天处理器
        ChatRequestMessageHandler chatHandler = new ChatRequestMessageHandler();
        //群组创建处理器
        GroupCreateRequestMessageHandler groupCreateHandler = new GroupCreateRequestMessageHandler();
        //群聊发送处理器
        GroupChatRequestMessageHandler groupChatHandler = new GroupChatRequestMessageHandler();
        //退出处理器
        QuitHandler quitHandler = new QuitHandler();
        try {
            final ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.channel(NioServerSocketChannel.class);
            bootstrap.group(boss, worker);
            bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(new ProcotolFrameDecoder());
                    ch.pipeline().addLast(LOG);
                    ch.pipeline().addLast(MESSAGE);
                    ch.pipeline().addLast(new IdleStateHandler(5,0,0));
                    //即为入站处理器、也为出站处理器
                    ch.pipeline().addLast(new ChannelDuplexHandler(){
                        //用来触发特殊事件
                        @Override
                        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
                            IdleStateEvent event = (IdleStateEvent) evt;
                            //读空闲
                            if (event.state() == IdleState.WRITER_IDLE) {
                                log.debug("读空闲已经超过5秒");

                            }
                            super.userEventTriggered(ctx, evt);
                        }
                    });
                    ch.pipeline().addLast(loginHandler);
                    ch.pipeline().addLast(chatHandler);
                    ch.pipeline().addLast(groupCreateHandler);
                    ch.pipeline().addLast(groupChatHandler);
                    ch.pipeline().addLast(quitHandler);
                }
            });

            ChannelFuture channelFuture = bootstrap.bind(8080).sync();
            channelFuture.channel().closeFuture().sync();

        } catch (InterruptedException e) {

            log.error("server error", e);

        } finally {
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }
    }


}
